package com.tcm.smarthealth.controller;

import com.tcm.smarthealth.common.ApiResponse;
import com.tcm.smarthealth.common.exception.BusinessException;
import com.tcm.smarthealth.dto.ImageRecordResponse;
import com.tcm.smarthealth.enums.ImageAnalysisType;
import com.tcm.smarthealth.security.AuthContext;
import com.tcm.smarthealth.security.AuthenticatedUser;
import com.tcm.smarthealth.service.ImageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Tag(name = "影像分析", description = "图片上传与智能分析接口")
@RestController
@RequestMapping("/api/v1/images")
@Validated
public class ImageController {

    private final ImageService imageService;

    public ImageController(ImageService imageService) {
        this.imageService = imageService;
    }

    @Operation(summary = "上传图片并执行模拟分析")
    @PostMapping("/upload")
    public ApiResponse<ImageRecordResponse> uploadImage(
            @RequestParam("file") MultipartFile file,
            @RequestParam("analysisType") String analysisType) throws IOException {
        AuthenticatedUser user = requireLogin();
        ImageAnalysisType type = ImageAnalysisType.fromCode(analysisType);
        ImageRecordResponse response = imageService.uploadAndAnalyze(file, type, user.getId());
        return ApiResponse.success(response);
    }

    @Operation(summary = "获取图片分析记录")
    @GetMapping
    public ApiResponse<List<ImageRecordResponse>> listRecords(
            @RequestParam(value = "analysisType", required = false) String analysisType,
            @RequestParam(value = "page", defaultValue = "1") int page,
            @RequestParam(value = "size", defaultValue = "10") int size) {
        AuthenticatedUser user = requireLogin();
        ImageAnalysisType type = analysisType != null && !analysisType.isBlank()
                ? ImageAnalysisType.fromCode(analysisType)
                : null;
        List<ImageRecordResponse> responses = imageService.listRecords(user.getId(), type, page, size);
        return ApiResponse.success(responses);
    }

    @Operation(summary = "获取单条图片分析结果")
    @GetMapping("/{id}")
    public ApiResponse<ImageRecordResponse> getRecord(@PathVariable("id") String id) {
        AuthenticatedUser user = requireLogin();
        ImageRecordResponse response = imageService.getRecord(id, user.getId());
        return ApiResponse.success(response);
    }

    @Operation(summary = "预览原始图片")
    @GetMapping("/{id}/preview")
    public ResponseEntity<Resource> preview(@PathVariable("id") String id) {
        AuthenticatedUser user = requireLogin();
        Resource resource = imageService.loadPreview(id, user.getId());

        String contentType = resource instanceof org.springframework.data.mongodb.gridfs.GridFsResource
                ? ((org.springframework.data.mongodb.gridfs.GridFsResource) resource).getContentType()
                : MediaType.APPLICATION_OCTET_STREAM_VALUE;

        ImageRecordResponse record = imageService.getRecord(id, user.getId());
        String filename = record.getFilename();
        String encodedName = URLEncoder.encode(filename, StandardCharsets.UTF_8).replaceAll("\\+", "%20");

        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM_VALUE))
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + encodedName + "\"")
                .body(resource);
    }

    private AuthenticatedUser requireLogin() {
        AuthenticatedUser user = AuthContext.getCurrentUser();
        if (user == null) {
            throw new BusinessException(HttpStatus.UNAUTHORIZED, "登录已失效，请重新登录");
        }
        return user;
    }
}

